`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2024/12/16 16:10:33
// Design Name: 
// Module Name: dbuf_ctrl
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module dbuf_ctrl#(
    parameter  DATA_WIDTH = 64
)(
    input                       adc_data_clk   ,
    input                       adc_data_rstn  ,//clock domain : adc_data_clk
    input  [DATA_WIDTH-1:0]     adc_data_all   ,//clock domain : adc_data_clk
    input                       adc_wvs_clk    ,
    input                       Tri_pluse_start,
    input                       Tri_pluse_stop ,    
    input                       Tri_pluse_clk  ,  
    //dbuf interface
    output                      ud_wclk        ,//clock domain : adc_data_clk
    output [DATA_WIDTH-1:0]     ud_wdata       ,//clock domain : adc_data_clk
    output                      ud_wde         ,//clock domain : adc_data_clk
    output                      ud_wfifo_rst   ,//clock domain : ud_wclk
    output                      ud_wvs         ,//clock domain : ud_wvs_clk
    output                      ud_wvs_clk     ,
    input                       ud_wfull       ,//clock domain : adc_data_clk
    input                       fdma_wirq       //clock domain : ui_clk
    );

  wire ud_pluse_start   ;
  reg  ud_pluse_start_r1;
  reg  ud_pluse_start_r2;
  wire ud_pluse_stop    ;
  reg  ud_pluse_stop_r1 ;
  reg  ud_pluse_stop_r2 ;
////////////////////////////////////////////Tri_pluse_start////////////////////////////////////////////////
  //跨时钟域处理 : Tri_pluse_clk ---> ud_wclk  (要求trigger_pluse信号足够dest_clk采2次以上)
  xpm_cdc_pulse #(
      .DEST_SYNC_FF(4),   // DECIMAL; range: 2-10
      .INIT_SYNC_FF(0),   // DECIMAL; 0=disable simulation init values, 1=enable simulation init values
      .REG_OUTPUT(0),     // DECIMAL; 0=disable registered output, 1=enable registered output
      .RST_USED(0),       // DECIMAL; 0=no reset, 1=implement reset
      .SIM_ASSERT_CHK(0)  // DECIMAL; 0=disable simulation messages, 1=enable simulation messages
   )
  xpm_cdc_pulse_start (
      .dest_pulse   (ud_pluse_start    ),
      .dest_clk     (ud_wclk           ),
      .src_clk      (Tri_pluse_clk     ),      
      .src_pulse    (Tri_pluse_start   )  
   );

  always @(posedge adc_data_clk ) begin
      ud_pluse_start_r1  <= ud_pluse_start    ;
      ud_pluse_start_r2  <= ud_pluse_start_r1 ;
  end
////////////////////////////////////////////Tri_pluse_stop////////////////////////////////////////////////
  //跨时钟域处理 : Tri_pluse_clk ---> ud_wclk  (要求trigger_pluse信号足够dest_clk采2次以上)
  xpm_cdc_pulse #(
      .DEST_SYNC_FF(4),   // DECIMAL; range: 2-10
      .INIT_SYNC_FF(0),   // DECIMAL; 0=disable simulation init values, 1=enable simulation init values
      .REG_OUTPUT(0),     // DECIMAL; 0=disable registered output, 1=enable registered output
      .RST_USED(0),       // DECIMAL; 0=no reset, 1=implement reset
      .SIM_ASSERT_CHK(0)  // DECIMAL; 0=disable simulation messages, 1=enable simulation messages
   )
  xpm_cdc_pulse_stop (
      .dest_pulse   (ud_pluse_stop     ),
      .dest_clk     (ud_wclk           ),
      .src_clk      (Tri_pluse_clk     ),      
      .src_pulse    (Tri_pluse_stop    )  
   );

  always @(posedge adc_data_clk ) begin
      ud_pluse_stop_r1  <= ud_pluse_stop    ;
      ud_pluse_stop_r2  <= ud_pluse_stop_r1 ;
  end

////////////////////////////////////////////state machine////////////////////////////////////////////////
  reg [7:0]   state         ;
  reg         ud_wfifo_rst_r;
  reg         ud_wvs_r      ;
  reg         ud_wde_r      ;
  reg [15:0]  dly_cnt       ;

  always @(posedge adc_data_clk ) begin
    if(!adc_data_rstn) begin
      state           <= 8'd0;
      ud_wfifo_rst_r  <= 1'b1;
      ud_wvs_r        <= 1'b0;
      ud_wde_r        <= 1'b0;
      dly_cnt         <= 16'd0;
    end
    else begin
      case (state)
        8'd0: begin
          ud_wfifo_rst_r <= 1'b0;
          if({ud_pluse_start_r1,ud_pluse_start_r2}==2'b10)  //上升沿触发
            state <= 8'd1;
          else
            state <= 8'd0;
        end
        8'd1: begin     //复位dbuf的写FIFO 以清空fifo中的剩余数据
          ud_wfifo_rst_r <= 1'b1;
          state          <= 8'd2;
        end
        8'd2: begin
          ud_wfifo_rst_r <= 1'b0;
          if(dly_cnt>=16'd50) begin //延时计数保证fifo复位完成
            dly_cnt <= 16'd0;
            state   <= 8'd3;
          end
          else begin
            dly_cnt <= dly_cnt + 1'b1;
            state   <= 8'd2;
          end
        end
        8'd3: begin     //开始写fifo
          ud_wvs_r <= 1'b1;
          ud_wde_r <= ~ud_wfull;
          state    <= 8'd4;
        end
        8'd4: begin
          if({ud_pluse_stop_r1,ud_pluse_stop_r2}==2'b10) begin//停止写指令触发
            ud_wvs_r <= 1'b0;
            ud_wde_r <= 1'b0;
            state    <= 8'd0;
          end
          else begin
            ud_wvs_r <= ud_wvs_r;
            ud_wde_r <= ud_wde_r;
            state    <= 8'd4;
          end
        end
        // 8'd3: begin

        // end
        default: state <= 8'd0;
      endcase
    end
  end


  assign ud_wclk      = adc_data_clk  ;
  assign ud_wdata     = adc_data_all  ;
  assign ud_wvs_clk   = adc_wvs_clk   ;

  assign ud_wvs       = ud_wvs_r      ;
  assign ud_wde       = ud_wde_r      ;
  assign ud_wfifo_rst = ud_wfifo_rst_r;


// ila_256bit ila_256bit (
// 	.clk(adc_data_clk), // input wire clk


// 	.probe0({
//     'b0,
//     state,
//     ud_wvs_r,
//     ud_wde_r,
//     ud_wfifo_rst_r,
//     dly_cnt
//   }) // input wire [255:0] probe0
// );


endmodule
